package com.jugheadzhou.emrpoc.service.impl;

import com.alibaba.fastjson.JSON;
import com.jugheadzhou.emrpoc.common.EmrResultCode;
import com.jugheadzhou.emrpoc.common.exception.EmrBusinessException;
import com.jugheadzhou.emrpoc.common.utils.JsonUtil;
import com.jugheadzhou.emrpoc.dto.MedicalRecordContentDto;
import com.jugheadzhou.emrpoc.dto.MedicalRecordContentPublishDto;
import com.jugheadzhou.emrpoc.dto.SimpleContentItem;
import com.jugheadzhou.emrpoc.mapper.MedicalRecordContentMapper;
import com.jugheadzhou.emrpoc.mapper.MedicalRecordMapper;
import com.jugheadzhou.emrpoc.model.MedicalRecord;
import com.jugheadzhou.emrpoc.model.MedicalRecordContent;
import com.jugheadzhou.emrpoc.service.MedicalRecordContentService;
import com.jugheadzhou.emrpoc.vo.MedicalRecordContentVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 病历内容业务层
 *
 * @author jugheadzhou
 * @date 2021-10-24
 */
@Slf4j
@Service
public class MedicalRecordContentServiceImpl implements MedicalRecordContentService {

    @Resource
    private MedicalRecordContentMapper medicalRecordContentMapper;

    @Resource
    private MedicalRecordMapper medicalRecordMapper;

    /**
     * 病历内容查询
     *
     * @param recordId
     * @return
     */
    @Override
    public MedicalRecordContentVo info(String recordId) {
        MedicalRecordContentVo vo = new MedicalRecordContentVo();
        MedicalRecordContent maxVersion = medicalRecordContentMapper.selectByRecordIdAndMaxVersion(recordId);
        if (maxVersion != null){
            BeanUtils.copyProperties(maxVersion, vo);
            if (StringUtils.isNotBlank(maxVersion.getContent())){
                vo.setContentItemList(JsonUtil.string2Object(maxVersion.getContent(), ArrayList.class, SimpleContentItem.class));
            }
        }
        return vo;
    }

    /**
     * 病历内容保存
     *
     * @param contentDto 保存的病历内容对象
     * @return
     */
    @Override
    public MedicalRecordContent save(MedicalRecordContentDto contentDto) {
        // 验证参数以及逻辑
        saveValidated(contentDto);
        // 入库
        MedicalRecordContent toInsertContent = new MedicalRecordContent();
        BeanUtils.copyProperties(contentDto, toInsertContent);
        toInsertContent.setRevision(contentDto.getFromRevision() + 1);
        toInsertContent.setCreatedBy("todo");
        toInsertContent.setCreateTime(LocalDateTime.now());
        medicalRecordContentMapper.insert(toInsertContent);
        log.info("病历内容保存结束");
        return toInsertContent;
    }


    /**
     * 病历内容完成/取消完成
     *
     * @param publishDto 完成的病历内容对象
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public MedicalRecordContent complete(MedicalRecordContentPublishDto publishDto) {
        // 验证参数以及逻辑
        MedicalRecordContent maxVersionContent = completeValidated(publishDto);
        Integer publish = publishDto.getPublish();
        // 更新病历主表状态
        MedicalRecord medicalRecord = new MedicalRecord();
        medicalRecord.setId(publishDto.getRecordId());
        medicalRecord.setPublished(publish);
        medicalRecordMapper.updateByPrimaryKeySelective(medicalRecord);
        // 完成
        if (publish == 1) {
            maxVersionContent.setPublished(publish);
            maxVersionContent.setPublishedBy("completed user");
            maxVersionContent.setPublishTime(LocalDateTime.now());
            medicalRecordContentMapper.updateByPrimaryKeySelective(maxVersionContent);
            log.info("病历内容完成结束");
            // 取消完成
        } else {
            MedicalRecordContent cancelContent = new MedicalRecordContent();
            cancelContent.setPublished(publish);
            cancelContent.setRecordId(publishDto.getRecordId());
            cancelContent.setFromRevision(maxVersionContent.getRevision());
            cancelContent.setRevision(maxVersionContent.getRevision() + 1);
            cancelContent.setCreatedBy("cancel complete user");
            cancelContent.setCreateTime(LocalDateTime.now());
            cancelContent.setContent(maxVersionContent.getContent());
            medicalRecordContentMapper.insert(cancelContent);
            log.info("病历内容取消完成结束");
        }

        return maxVersionContent;
    }

    /**
     * 病历内容打印
     *
     * @param contentDto 打印的病历内容对象
     * @return
     */
    @Override
    public int print(MedicalRecordContentDto contentDto) {
        // 验证
        MedicalRecordContent maxVersionContent = printValidated(contentDto);
        // 入库
        maxVersionContent.setPrinted(1);
        maxVersionContent.setLastPrintedBy("Print User");
        maxVersionContent.setLastPrintTime(LocalDateTime.now());
        int count = medicalRecordContentMapper.updateByPrimaryKeySelective(maxVersionContent);
        log.info("病历内容打印结束");
        return count;
    }

    /**
     * 验证参数以及逻辑
     *
     * @param contentDto
     */
    private void saveValidated(MedicalRecordContentDto contentDto) {
        Integer fromRevision = contentDto.getFromRevision();
        String recordId = contentDto.getRecordId();
        String content = contentDto.getContent();
        if (StringUtils.isNotBlank(content)){
            try {
                JsonUtil.string2Object(content, SimpleContentItem.class);
            }catch (Exception e){
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_NOT_LEGAL);
            }
        }
        if (fromRevision == null || fromRevision < 0) {
            throw new EmrBusinessException(EmrResultCode.MR_CONTENT_VERSION_NOT_LEGAL);
        } else if (fromRevision == 0) {
            if (medicalRecordContentMapper.exitsByRecordId(recordId) == 1) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_FIRST_VERSION_ALREADY);
            }
        } else {
            // 找到最新的病历内容
            MedicalRecordContent maxVersionContent = medicalRecordContentMapper.selectByRecordIdAndMaxVersion(recordId);
            if (maxVersionContent == null) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_NOT_EXITS);
            } else if (!maxVersionContent.getRevision().equals(fromRevision)) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_VERSION_NOT_NEWEST);
            } else if (maxVersionContent.getPublished() == 1) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_COMPLETED_ALREADY);
            }
        }
    }

    /**
     * 验证完成病历内容的参数以及逻辑
     *
     * @param publishDto
     * @return
     */
    private MedicalRecordContent completeValidated(MedicalRecordContentPublishDto publishDto) {
        Integer fromRevision = publishDto.getFromRevision();
        String recordId = publishDto.getRecordId();
        Integer publish = publishDto.getPublish();
        if (publish == null || !(publish == 0 || publish == 1)) {
            throw new EmrBusinessException(EmrResultCode.MR_CONTENT_ACTION_NOT_LEGAL);
        }
        if (fromRevision > 0) {
            // 找到最新的病历内容
            MedicalRecordContent maxVersionContent = medicalRecordContentMapper.selectByRecordIdAndMaxVersion(recordId);
            if (maxVersionContent == null) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_NOT_EXITS);
            } else if (!maxVersionContent.getRevision().equals(fromRevision)) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_VERSION_NOT_NEWEST);
            } else if (publish == 0 && maxVersionContent.getPublished() == 0) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_NOT_COMPLETED);
            } else if (publish == 1 && maxVersionContent.getPublished() == 1) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_COMPLETED_ALREADY);
            }
            return maxVersionContent;
        } else {
            throw new EmrBusinessException(EmrResultCode.MR_CONTENT_VERSION_NOT_LEGAL);
        }
    }

    /**
     * 验证打印病历内容的参数以及逻辑
     *
     * @param contentDto
     * @return
     */
    private MedicalRecordContent printValidated(MedicalRecordContentDto contentDto) {
        Integer fromRevision = contentDto.getFromRevision();
        String recordId = contentDto.getRecordId();
        if (fromRevision > 0) {
            // 找到最新的病历内容
            MedicalRecordContent maxVersionContent = medicalRecordContentMapper.selectByRecordIdAndMaxVersion(recordId);
            if (maxVersionContent == null) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_NOT_EXITS);
            } else if (!maxVersionContent.getRevision().equals(fromRevision)) {
                throw new EmrBusinessException(EmrResultCode.MR_CONTENT_VERSION_NOT_NEWEST);
            }
            return maxVersionContent;
        } else {
            throw new EmrBusinessException(EmrResultCode.MR_CONTENT_VERSION_NOT_LEGAL);
        }
    }

}
